import 'dart:async';

import 'package:casdon/app/config/env/common_config.dart';
import 'package:casdon/common/service/tuya_service.dart';
import 'package:casdon/core/logger/log.dart';
import 'package:casdon/modules/device/application/notification/device_discovery_provider.dart';
import 'package:casdon/modules/device/domain/states/pair_state.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:tuya_home_sdk_flutter/tuya_home_sdk_flutter.dart';

class PairNetNotifier extends StateNotifier<List<DevicePairState>> {
  PairNetNotifier(this.ref) : super([]);

  final Ref ref;

  final List<String> _successfulDevices = [];
  StreamSubscription<BleBatchConfigResult>? _batchSubscription;
  final List<_SinglePairTask> _singleQueue = [];
  bool _isProcessingSingleQueue = false;
  bool _stopRequested = false;
  String _normalizeUuid(String? uuid) => (uuid ?? '').toLowerCase();
  bool _isSameUuid(String? left, String? right) {
    if (left == null || right == null) {
      return false;
    }
    return _normalizeUuid(left) == _normalizeUuid(right);
  }

  // 释放前的清理操作：移除已配网成功的设备
  void _performCleanupOperations() {
    Log.i('执行清理操作：移除已配网成功的设备');

    // 获取所有配网成功的设备ID
    final successfulDevices = _getSuccessfulDeviceUuids();

    if (successfulDevices.isNotEmpty) {
      // 从发现列表中移除这些设备
      Future.microtask(() {
        // if (ref.mounted) {
        Log.i('标记需要移除的设备uuid: ${successfulDevices.join(', ')}');
        ref
            .read(deviceDiscoveryProvider.notifier)
            .removeDeviceList(successfulDevices);
        // }
      });
    }
  }

  @override
  void dispose() async {
    _performCleanupOperations();
    stopAllPairing();

    Log.i('♻️ 释放PairNetNotifier资源');
    super.dispose();
  }

  void stop() async {
    await TuyaService().stopBleWifiConfig();
  }

  /// 停止配网，并清空串行队列
  void stopAllPairing() async {
    _stopRequested = true;
    _batchSubscription?.cancel();
    _batchSubscription = null;
    unawaited(TuyaService().stopBatchBleConfig());
    await TuyaService().stopBleWifiConfig();

    _singleQueue.clear();
    _isProcessingSingleQueue = false;
    if (mounted) {
      _resetQueuedStates();
      Log.i('已停止配网并清空串行队列');
    } else {
      Log.i('已停止配网（已卸载，不再重置状态）');
    }
  }

  // 获取所有配网成功的设备ID
  Set<String> _getSuccessfulDeviceUuids() {
    return state
        .where((deviceState) => deviceState.state == PairState.success)
        .map((deviceState) => deviceState.deviceModel!.uuid)
        .toSet();
  }

  // // 获取设备状态
  // PairState getState(String deviceId) {
  //   return state
  //       .firstWhere(
  //         (e) => e.deviceModel?.devId == deviceId,
  //         orElse: () => DevicePairState(deviceId, PairState.idle),
  //       )
  //       .state;
  // }

  // 更新状态
  void _updateState(
    ThingSmartDeviceModel devModel,
    PairState newState,
    int errorCode,
    String errorMsg, {
    bool? inQueue,
  }) {
    final normalizedUuid = _normalizeUuid(devModel.uuid);
    final updatedStates = <DevicePairState>[];
    var replaced = false;
    for (final entry in state) {
      final entryUuid = entry.deviceModel?.uuid;
      if (_normalizeUuid(entryUuid) == normalizedUuid && !replaced) {
        updatedStates.add(
          DevicePairState(
            deviceModel: devModel,
            state: newState,
            errorCode: errorCode,
            errorMsg: errorMsg,
            inQueue: inQueue ?? entry.inQueue,
          ),
        );
        replaced = true;
      } else {
        updatedStates.add(entry);
      }
    }
    if (!replaced) {
      updatedStates.add(
        DevicePairState(
          deviceModel: devModel,
          state: newState,
          errorCode: errorCode,
          errorMsg: errorMsg,
          inQueue: inQueue ?? false,
        ),
      );
    }
    state = updatedStates;
  }

  // 执行配网(单个设备)
  Future<void> startPairingSigle({
    required ThingSmartDeviceModel device,
    required String ssid,
    required String password,
  }) async {
    _updateState(device, PairState.process, 0, '', inQueue: false);

    try {
      final result = await TuyaService()
          .startPairNet(
            deviceUuid: device.uuid,
            deviceProductId: device.productId,
            ssid: ssid,
            password: password,
          )
          .timeout(
            const Duration(seconds: CommonConfig.pairNet_device_timeout),
          );

      if (result != null) {
        _updateState(result, PairState.success, 0, '', inQueue: false);
        // 记录配网成功的设备，但不立即移除
        Log.i('🎉 设备配网成功，记录uuid: ${device.uuid}');
        _successfulDevices.add(device.uuid);
      }
    } on TimeoutException {
      if (!mounted) return;
      _updateState(device, PairState.failed, 0, '配网超时', inQueue: false);
      rethrow; // 可以继续向上抛出或处理超时逻辑
    } on PlatformException catch (e, st) {
      final code = int.tryParse(e.code) ?? 0;
      _updateState(device, PairState.failed, code, '配网超时', inQueue: false);
    } catch (e) {
      if (!mounted) return;
      _updateState(device, PairState.failed, 0, '配网失败', inQueue: false);
      rethrow;
    }
  }

  /// 将单设备配网排队串行执行
  Future<void> enqueueSinglePairings({
    required List<ThingSmartDeviceModel> devices,
    required String ssid,
    required String password,
  }) async {
    _stopRequested = false;
    final existingUuids = _singleQueue
        .map((e) => _normalizeUuid(e.device.uuid))
        .toSet();
    for (final d in devices.where((e) => e.uuid.isNotEmpty)) {
      final uuid = _normalizeUuid(d.uuid);
      if (existingUuids.contains(uuid)) continue;
      final current = state.firstWhere(
        (e) => _isSameUuid(e.deviceModel?.uuid, uuid),
        orElse: () => DevicePairState(
          deviceModel: d,
          state: PairState.idle,
          errorCode: 0,
          errorMsg: '',
        ),
      );
      if (current.state != PairState.process &&
          current.state != PairState.success) {
        _updateState(d, PairState.process, 0, '', inQueue: true);
      }
      _singleQueue.add(
        _SinglePairTask(device: d, ssid: ssid, password: password),
      );
      existingUuids.add(uuid);
    }
    await _processSingleQueue();
  }

  Future<void> _processSingleQueue() async {
    if (_isProcessingSingleQueue) return;
    _isProcessingSingleQueue = true;
    while (_singleQueue.isNotEmpty && !_stopRequested) {
      final task = _singleQueue.removeAt(0);
      _updateState(task.device, PairState.process, 0, '', inQueue: false);
      try {
        await startPairingSigle(
          device: task.device,
          ssid: task.ssid,
          password: task.password,
        );
      } catch (_) {
        // 已在 startPairingSigle 中更新状态，忽略异常继续下一个
      }
    }
    _isProcessingSingleQueue = false;
  }

  Future<void> startBatchPairing({
    required List<ThingSmartDeviceModel> devices,
    required String ssid,
    required String password,
  }) async {
    final targets = devices.where((device) => device.uuid.isNotEmpty).where((
      device,
    ) {
      final current = state.firstWhere(
        (e) => _isSameUuid(e.deviceModel?.uuid, device.uuid),
        orElse: () => DevicePairState(
          deviceModel: device,
          state: PairState.idle,
          errorCode: -1,
          errorMsg: '配网超时',
        ),
      );
      return current.state != PairState.process &&
          current.state != PairState.success;
    }).toList();
    final limitedTargets = targets.take(3).toList();
    if (limitedTargets.isEmpty) {
      return;
    }

    for (final device in limitedTargets) {
      _updateState(device, PairState.process, 0, '配网超时', inQueue: false);
    }

    _batchSubscription ??= TuyaService().batchConfigStream().listen(
      _handleBatchEvent,
      onError: (error, stackTrace) {
        Log.e('批量配网结果监听异常', error, stackTrace);
      },
    );

    final uuids = limitedTargets.map((device) => device.uuid).toList();
    final success = await TuyaService().startBatchBleConfig(
      uuids: uuids,
      ssid: ssid,
      password: password,
    );
    if (!success) {
      for (final device in limitedTargets) {
        _updateState(device, PairState.failed, 0, '配网失败', inQueue: false);
      }
    }
  }

  // 重置所有设备状态
  void resetAllStates() {
    state = state
        .map(
          (e) => DevicePairState(
            deviceModel: e.deviceModel,
            state: PairState.idle,
            errorCode: 0,
            errorMsg: '',
            inQueue: false,
          ),
        )
        .toList();
  }

  void _resetQueuedStates() {
    state = state
        .map(
          (e) => DevicePairState(
            deviceModel: e.deviceModel,
            state: PairState.idle,
            errorCode: 0,
            errorMsg: '',
            inQueue: false,
          ),
        )
        .toList();
  }

  // 重置单个设备状态
  void resetDeviceState(ThingSmartDeviceModel devModel) {
    _updateState(devModel, PairState.idle, 0, '', inQueue: false);
  }

  void updateDeviceName({required String uuid, required String name}) {
    state = state.map((deviceState) {
      final model = deviceState.deviceModel;
      if (model != null && _isSameUuid(model.uuid, uuid)) {
        final updatedJson = model.toJson();
        updatedJson['name'] = name;
        final updatedModel = ThingSmartDeviceModel.fromJson(updatedJson);
        return DevicePairState(
          deviceModel: updatedModel,
          state: deviceState.state,
          errorCode: deviceState.errorCode,
          errorMsg: deviceState.errorMsg,
          inQueue: deviceState.inQueue,
        );
      }
      return deviceState;
    }).toList();
  }

  void _handleBatchEvent(BleBatchConfigResult event) {
    if (event.uuid.isEmpty) {
      return;
    }
    final existing = state.firstWhere(
      (deviceState) => _isSameUuid(deviceState.deviceModel?.uuid, event.uuid),
      orElse: () => DevicePairState(
        deviceModel: event.device,
        state: PairState.idle,
        errorCode: 0,
        errorMsg: '',
      ),
    );
    final model = event.device ?? existing.deviceModel;
    if (model == null) {
      return;
    }
    if (event.success && event.device != null) {
      _updateState(event.device!, PairState.success, 0, '', inQueue: false);
      _successfulDevices.add(event.device!.uuid);
    } else {
      _updateState(
        model,
        PairState.failed,
        _toInt(event.errorCode),
        event.errorMessage ?? '配网失败',
        inQueue: false,
      );
    }
  }

  int _toInt(dynamic value) {
    if (value is int) return value;
    if (value is String) return int.tryParse(value) ?? 0;
    return 0;
  }
}

final pairNetProvider =
    StateNotifierProvider.autoDispose<PairNetNotifier, List<DevicePairState>>((
      ref,
    ) {
      final notifier = PairNetNotifier(ref);
      return notifier;
    });
final removedDevicesProvider = StateProvider<Set<String>>((ref) => <String>{});

class _SinglePairTask {
  final ThingSmartDeviceModel device;
  final String ssid;
  final String password;

  _SinglePairTask({
    required this.device,
    required this.ssid,
    required this.password,
  });
}
